/**
 *
 * User: Zhikang.Peng
 * Date: 2018/04/12 16:33
 */
package comparisons

import (
	"gitee.com/thghh/jvmgo/instructions/base"
	"gitee.com/thghh/jvmgo/rtda"
)

// 比较栈顶两int型数值大小，当结果等于0时跳转
type IF_ICMPEQ struct{ base.BranchInstruction }

func (self *IF_ICMPEQ) Execute(frame *rtda.Frame) {
	v1, v2 := _icmpPop(frame)
	if v1 == v2 {
		base.Branch(frame, self.Offset)
	}
}

// 比较栈顶两int型数值大小，当结果不等于0时跳转
type IF_ICMPNE struct{ base.BranchInstruction }

func (self *IF_ICMPNE) Execute(frame *rtda.Frame) {
	v1, v2 := _icmpPop(frame)
	if v1 != v2 {
		base.Branch(frame, self.Offset)
	}
}

// 比较栈顶两int型数值大小，当结果小于0时跳转
type IF_ICMPLT struct{ base.BranchInstruction }

func (self *IF_ICMPLT) Execute(frame *rtda.Frame) {
	v1, v2 := _icmpPop(frame)
	if v1 < v2 {
		base.Branch(frame, self.Offset)
	}
}

// 比较栈顶两int型数值大小，当结果小于等于0时跳转
type IF_ICMPLE struct{ base.BranchInstruction }

func (self *IF_ICMPLE) Execute(frame *rtda.Frame) {
	v1, v2 := _icmpPop(frame)
	if v1 <= v2 {
		base.Branch(frame, self.Offset)
	}
}

// 比较栈顶两int型数值大小，当结果大于0时跳转
type IF_ICMPGT struct{ base.BranchInstruction }

func (self *IF_ICMPGT) Execute(frame *rtda.Frame) {
	v1, v2 := _icmpPop(frame)
	if v1 > v2 {
		base.Branch(frame, self.Offset)
	}
}

// 比较栈顶两int型数值大小，当结果大于等于0时跳转
type IF_ICMPGE struct{ base.BranchInstruction }

func (self *IF_ICMPGE) Execute(frame *rtda.Frame) {
	v1, v2 := _icmpPop(frame)
	if v1 >= v2 {
		base.Branch(frame, self.Offset)
	}
}

/**
 * 从操作数栈中获取两个比较值
 */
func _icmpPop(frame *rtda.Frame) (v1, v2 int32) {
	stack := frame.OperandStack()
	v2 = stack.PopInt()
	v1 = stack.PopInt()
	return
}
